<?php

namespace App\Http\Middleware;

use Closure;
use App\Http\Service\UserService;
use App\Http\Service\TokenService;
use App\Http\Model\User;

class AuthMiddleware
{
    private $userService;
    private $tokenService;

    public function __construct(UserService $userService, TokenService $tokenService)
    {
        $this->userService = $userService;
        $this->tokenService = $tokenService;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  int  $auth  1 临时用户和正式用户 2 正式用户 3 无需auth验证
     * @return mixed
     */
    public function handle($request, Closure $next, $auth = 1)
    {
        if (!in_array($auth, [1, 2, 3]))
            return response()->json(toJSON('', \Constant::FAILED));

        // system-type system-version 所有接口必传
        $systemType = $request->header('system-type');
        $systemVersion = $request->header('system-version');

//        if ($systemType == null)
//            $systemType = $request->input('system-type');
//
//        if ($systemVersion == null)
//            $systemVersion = $request->input('system-version');
//
//        if ($systemType == null)
//            return response()->json(toJSON('', \Constant::SYSTEM_TYPE_EMPTY));
//
//        if ($systemVersion == null)
//            return response()->json(toJSON('', \Constant::SYSTEM_VERSION_EMPTY));

        $token = $request->header('token');
        if ($token == null)
            $token = $request->input('token');

        if ($token == null && in_array($auth, [1, 2]))
            return response()->json(toJSON('', \Constant::TOKEN_EMPTY));

        // 加密验证
        if ('app/captcha' != $request->path() && !$this->checkSign($request))
            return response()->json(toJSON('', \Constant::SIGN_ERROR));

        $user = new User;
        $user->id = 0;
        $user->mobile = '';
        $user->nickname = md5(microtime() . rand(0, 5000));

        $isCreateToken = true;

        if ($token != null) {

            try {
                $jwt = decodeToken($token);
            } catch (\Exception $e) {
                return response()->json(toJSON('', \Constant::TOKEN_ERROR));
            }

            $user->token = $token;

            if ($jwt->id != 0) {
                $user = $this->userService->find($jwt->id);

                if ($user == null)
                    return response()->json(toJSON('', \Constant::TOKEN_ERROR));

                // token是否过期
                if ($user->token != $token)
                    return response()->json(toJSON('', \Constant::TOKEN_EXPIRED));

                // 是否安全检查
                if ($user->risk_check == 1)
                    return response()->json(toJSON('', \Constant::RISK_CHECK));

            } else {
                $token = $this->tokenService->findFirstRowByFields(['token_crc32' => crc32($token), 'token' => $token]);
                if ($token == null)
                    return response()->json(toJSON('', \Constant::TOKEN_ERROR));
            }

            $isCreateToken = false;
        }

        if ($auth == 2 && $user->id == 0) {
            return response()->json(toJSON('', \Constant::NEED_LOGIN));
        }

        $request->attributes->add(['user' => $user, 'is_create_token' => $isCreateToken]);

        return $next($request);
    }

    private function checkSign($request)
    {
        $input = $request->input();

        $sign = $request->input('sign', '');

        unset($input['sign']);
        ksort($input);

        $str = '';
        foreach ($input as $v)
            $str .= $v;

        $str .= env('APP_SECRET_KEY');

        if (md5($str) == $sign)
            return true;

        return false;
    }
}
